module controller.AnnualReviewController;

import std.conv : to;
import std.json : JSONValue, parseJSON;

import archttp.HttpStatusCode : HttpStatusCode;
import archttp.HttpRequest : HttpRequest;
import archttp.HttpResponse : HttpResponse;
import mir.ser.json : serializeJson;

import model.AnnualReview;
import repository.AnnualReviewRepo;

import utils.RespData : RespData;
import utils.DataCache;
import utils.CacheKey : CacheKey;
import utils.ObjMapping : ObjMapping;
import utils.SecurityVerification : signValidator;

/** 
 * 年度点评控制器
 */
class AnnualReviewController
{

    AnnualReviewRepo _arRepo; // AnnualReview仓储
    this ()
    {
        // 注入AnnualReview仓储
        _arRepo = new AnnualReviewRepo();
    }

    /** 
     * 获取全部年度点评列表数据
     */
    public void getAllList (HttpRequest req, HttpResponse resp)
    {
        // 缓存中有数据直接取出返回
        auto data = cacheData.get(CacheKey.ANNUALREVIEW_ALLLIST_CACHE);
        if (!data.isNull)
        {
            resp.json(RespData.newData(200, "ok", data.get)).send();
            return;
        }

        AnnualReview[] annualReviewList = _arRepo.getAllAnnualReviewList();
        // 转换为Dto对象
        AnnualReviewDto[] annualReviewDtoList = [];
        foreach (an; annualReviewList)
        {
            annualReviewDtoList ~= ObjMapping.mappingToObject!(AnnualReviewDto, AnnualReview)(
                an);
        }

        // 设置缓存
        string jsonList = serializeJson(annualReviewDtoList);
        cacheData.put(CacheKey.ANNUALREVIEW_ALLLIST_CACHE, jsonList);

        resp.json(RespData.newData(200, "ok", jsonList)).send();
    }

    /** 
     * 获取年度点评列表数据
     *   - 视频类型（1：电视剧，2：电影，3：年度点评）
     */
    public void getList (HttpRequest req, HttpResponse resp)
    {
        import std.format : format;

        string vcateStr = req.query("vcate");
        if (vcateStr is null || vcateStr.length == 0)
        {
            resp.json(RespData.newData(400, "错误的请求")).send();
            return;
        }
        uint videoCate = to!uint(vcateStr);

        // 缓存中有数据直接取出返回
        auto data = cacheData.get(CacheKey.ANNUALREVIEW_LIST_CACHE ~ vcateStr);
        if (!data.isNull)
        {
            resp.json(RespData.newData(200, "ok", data.get)).send();
            return;
        }

        AnnualReview[] annualReviewList = _arRepo.getAnnualReviewList(videoCate);
        // 转换为Dto对象
        AnnualReviewDto[] annualReviewDtoList = [];
        foreach (an; annualReviewList)
        {
            annualReviewDtoList ~= ObjMapping.mappingToObject!(AnnualReviewDto, AnnualReview)(
                an);
        }

        // 设置缓存
        string jsonList = serializeJson(annualReviewDtoList);
        cacheData.put(CacheKey.ANNUALREVIEW_LIST_CACHE ~ vcateStr, jsonList);

        resp.json(RespData.newData(200, "ok", jsonList)).send();
    }

    /** 
     * 添加年度点评
     */
    public void addAnnualReview (HttpRequest req, HttpResponse resp)
    {
        JSONValue json = parseJSON(req.body());
        uint year = json["year"].get!uint;
        string comment = json["comment"].str;
        uint vcate = json["vCate"].get!uint;

        string sign = json["sign"].str;

        import std.format : format;

        string reqParamsStr = format("%s%s%s", year, vcate, comment);
        if (!signValidator(reqParamsStr, sign))
        {
            resp.code(HttpStatusCode.FORBIDDEN).json(RespData.newData(403, "签名不正确！")).send();
            return;
        }

        auto ar = new AnnualReviewDtoFromCreate(year, comment, vcate);
        bool res = _arRepo.addAnnualReview(ObjMapping.mappingToObject!(AnnualReview, AnnualReviewDtoFromCreate)(
                ar));
        if (!res)
        {
            resp.code(HttpStatusCode.INTERNAL_SERVER_ERROR)
                .json(RespData.newData(500, "error")).send();
            return;
        }
        resp.code(HttpStatusCode.CREATED).json(RespData.newData(200, "ok")).send();
    }

    /** 
     * 编辑年度点评
     */
    public void editAnnualReview (HttpRequest req, HttpResponse resp)
    {
        string idStr = req.param("id");
        if (idStr == "")
        {
            resp.json(RespData.newData(400, "错误的请求")).send();
        }
        uint id = to!uint(idStr);

        JSONValue json = parseJSON(req.body());
        uint year = json["year"].get!uint;
        string comment = json["comment"].str;

        string sign = json["sign"].str;

        import std.format : format;

        string reqParamsStr = format("%s%s", year, comment);
        if (!signValidator(reqParamsStr, sign))
        {
            resp.code(HttpStatusCode.FORBIDDEN).json(RespData.newData(403, "签名不正确！")).send();
            return;
        }

        auto ar = new AnnualReviewDtoFromUpdate(year, comment);
        bool res = _arRepo.updateAnnualReview(id, ObjMapping.mappingToObject!(AnnualReview, AnnualReviewDtoFromUpdate)(
                ar));
        if (!res)
        {
            resp.code(HttpStatusCode.INTERNAL_SERVER_ERROR)
                .json(RespData.newData(500, "error")).send();
            return;
        }
        resp.json(RespData.newData(200, "ok")).send();
    }

    /** 
     * 删除年度点评
     */
    public void deleteAnnualReview (HttpRequest req, HttpResponse resp)
    {
        string idStr = req.param("id");
        string sign = req.query("sign");
        if (idStr == "" || sign == "" || sign is null)
        {
            resp.json(RespData.newData(400, "错误的请求")).send();
        }
        uint id = to!uint(idStr);

        if (!signValidator(idStr, sign))
        {
            resp.code(HttpStatusCode.FORBIDDEN).json(RespData.newData(403, "签名不正确！")).send();
            return;
        }

        bool res = _arRepo.removeAnnualReview(id);
        if (!res)
        {
            resp.code(HttpStatusCode.INTERNAL_SERVER_ERROR)
                .json(RespData.newData(500, "error")).send();
            return;
        }
        resp.json(RespData.newData(200, "ok")).send();

    }

}
